package org.jrs.adaptadorDeJuegos.visores;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;

import javax.swing.DefaultListModel;
import javax.swing.JFrame;

import org.jrs.adaptadorDeJuegos.JuegoAdaptador;
import org.jrs.adaptadorDeJuegos.utiles.JuegoUtiles;

public class JuegoVisorGrabacion extends JFrame{

        private JuegoAdaptador jf;
        public HashSet<String> atributosSeguidos=new HashSet<String>();
        
        private ArrayList<Serializable> estadosLista=new ArrayList<Serializable>(); 
        
        public JuegoVisorGrabacion(JuegoAdaptador jf){
                setTitle("Grabacion");
        initComponents();
        this.jf=jf;
    }

    @SuppressWarnings("unchecked")
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        txtSeguimiento = new javax.swing.JTextArea();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        sldGrabacion = new javax.swing.JSlider();
        jLabel4 = new javax.swing.JLabel();
        jInactividad = new javax.swing.JLabel();
        btnPersistenciaGuardar = new javax.swing.JButton();
        btnPersistenciaRecuperar = new javax.swing.JButton();
        btnLimpiarGrabacion = new javax.swing.JButton();
        jScrollPane3 = new javax.swing.JScrollPane();
        lstVariables = new javax.swing.JList();
        btnAtributoQuitar = new javax.swing.JButton();
        btnAtributoSeguir = new javax.swing.JButton();
        jLabel5 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(null);

        jLabel1.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
        jLabel1.setText("Visor del modelo");
        getContentPane().add(jLabel1);
        jLabel1.setBounds(10, 10, 180, 22);

        txtSeguimiento.setColumns(20);
        txtSeguimiento.setEditable(false);
        txtSeguimiento.setRows(5);
        jScrollPane1.setViewportView(txtSeguimiento);

        jScrollPane2.setViewportView(jScrollPane1);

        getContentPane().add(jScrollPane2);
        jScrollPane2.setBounds(10, 60, 420, 150);

        jLabel2.setText("Persistencia");
        getContentPane().add(jLabel2);
        jLabel2.setBounds(10, 270, 150, 14);

        jLabel3.setText("Atributos disponibles");
        getContentPane().add(jLabel3);
        jLabel3.setBounds(440, 40, 180, 14);

        sldGrabacion.setMinimum(0);
        sldGrabacion.setMaximum(99);
        sldGrabacion.setValue(99);
        
        sldGrabacion.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                sldGrabacionStateChanged(evt);
            }
        });
        getContentPane().add(sldGrabacion);
        sldGrabacion.setBounds(10, 240, 420, 25);

        jLabel4.setText("Grabacion");
        getContentPane().add(jLabel4);
        jLabel4.setBounds(10, 220, 140, 14);

        jInactividad.setText("Estado: Grabando");
        getContentPane().add(jInactividad);
        jInactividad.setBounds(130, 220, 170, 14);

        btnPersistenciaGuardar.setText("Guardar");
        btnPersistenciaGuardar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnPersistenciaGuardarActionPerformed(evt);
            }
        });
        getContentPane().add(btnPersistenciaGuardar);
        btnPersistenciaGuardar.setBounds(100, 270, 140, 23);

        btnPersistenciaRecuperar.setText("Recuperar");
        btnPersistenciaRecuperar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnPersistenciaRecuperarActionPerformed(evt);
            }
        });
        getContentPane().add(btnPersistenciaRecuperar);
        btnPersistenciaRecuperar.setBounds(250, 270, 120, 23);

        btnLimpiarGrabacion.setText("Limpiar");
        btnLimpiarGrabacion.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnLimpiarGrabacionActionPerformed(evt);
            }
        });
        getContentPane().add(btnLimpiarGrabacion);
        btnLimpiarGrabacion.setBounds(380, 270, 110, 23);

        jScrollPane3.setViewportView(lstVariables);

        getContentPane().add(jScrollPane3);
        jScrollPane3.setBounds(440, 60, 180, 150);

        btnAtributoQuitar.setText("Quitar");
        btnAtributoQuitar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAtributoQuitarActionPerformed(evt);
            }
        });
        getContentPane().add(btnAtributoQuitar);
        btnAtributoQuitar.setBounds(523, 220, 100, 23);

        btnAtributoSeguir.setText("Seguir");
        btnAtributoSeguir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAtributoSeguirActionPerformed(evt);
            }
        });
        getContentPane().add(btnAtributoSeguir);
        btnAtributoSeguir.setBounds(440, 220, 80, 23);

        jLabel5.setText("Atributos en seguimiento");
        getContentPane().add(jLabel5);
        jLabel5.setBounds(10, 40, 190, 14);
      
        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds(480, 480, 640, 354);
    }

    private void btnPersistenciaGuardarActionPerformed(java.awt.event.ActionEvent evt) {
        try{
                FileOutputStream fos=new FileOutputStream("partida_guardada.dat");
                ObjectOutputStream dos=new ObjectOutputStream(fos);
                dos.writeObject(jf.eventoEstadoCapturar());
                dos.close();
                fos.close();
                System.out.println("Estado guardado");
        }catch(Exception e){
                e.printStackTrace();
        }
    }

    private void btnAtributoSeguirActionPerformed(java.awt.event.ActionEvent evt) {
        if (lstVariables.getSelectedIndex()>=0){
                atributosSeguidos.add(""+lstVariables.getSelectedValue());
        }
    }

    private void btnAtributoQuitarActionPerformed(java.awt.event.ActionEvent evt) {
        if (lstVariables.getSelectedIndex()>=0){
                String nombre=""+lstVariables.getSelectedValue();
                if (atributosSeguidos.contains(nombre)){
                        atributosSeguidos.remove(nombre);
                }
        }
    }

    private void btnPersistenciaRecuperarActionPerformed(java.awt.event.ActionEvent evt) {
        try{
                FileInputStream fis=new FileInputStream("partida_guardada.dat");
                ObjectInputStream dis=new ObjectInputStream(fis);
                Serializable objeto=(Serializable)(dis.readObject());
                dis.close();
                fis.close();
                jf.eventoEstadoReestablecer(objeto);
                System.out.println("Estado cargado");
        }catch(Exception e){
                e.printStackTrace();
        }       
    }

    private void btnLimpiarGrabacionActionPerformed(java.awt.event.ActionEvent evt) {
        estadosLista.clear();
    }

    private void sldGrabacionStateChanged(javax.swing.event.ChangeEvent evt) {
        if (jf.getTicksInactividad()!=1){
                int pos=sldGrabacion.getValue();
                int nP=pos*estadosLista.size()/100;
                jf.eventoEstadoReestablecer(estadosLista.get(nP));
                jf.setTicksInactividad(20);
                volcarEstado(estadosLista.get(nP));
        }
    }

    private javax.swing.JButton btnAtributoQuitar;
    private javax.swing.JButton btnAtributoSeguir;
    private javax.swing.JButton btnPersistenciaGuardar;
    private javax.swing.JButton btnPersistenciaRecuperar;
    private javax.swing.JButton btnLimpiarGrabacion;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jInactividad;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JList lstVariables;
    private javax.swing.JSlider sldGrabacion;
    private javax.swing.JTextArea txtSeguimiento;

    private int ultimosMetodos=0;
    private void refrescarListaAtributos(Serializable estado){
        Method[] metodos = estado.getClass().getDeclaredMethods();
        if (ultimosMetodos!=metodos.length){
            DefaultListModel dlm=new DefaultListModel();
            for(Method m : metodos){
                String metodo = m.getName();
                try{
                        if (metodo.startsWith("get")){
                        dlm.addElement(metodo);
                                
                        }
                }catch(Exception ex){
                    ex.printStackTrace();
                }
            }
            lstVariables.setModel(dlm);
            ultimosMetodos=metodos.length;
        }
    }
    
    public void refrescarTextoValores(Serializable estado){
        Method[] metodos = estado.getClass().getDeclaredMethods();
        String sTexto="";
        for(Method m : metodos){
            String nombre = m.getName();
            try{
                if (atributosSeguidos.contains(nombre)){
                        Object value = m.invoke(estado, new Object[0]);
                        sTexto+=nombre + "=" + value + "\n";
                }
            }catch(Exception ex){
                ex.printStackTrace();
            }
        }
        txtSeguimiento.setText(sTexto);
    }
    
    public void volcarEstado(Serializable estado){
        refrescarListaAtributos(estado);
        refrescarTextoValores(estado);
        if (jf.getTicksInactividad()==0){
                estadosLista.add(JuegoUtiles.clonarObjetoSerializable(estado));
                jInactividad.setText("Estado: Grabando");
        }
    }
    
    public void actualizarInactividad(){
        if (jf.getTicksInactividad()>0){
                if (jf.getTicksInactividad()==1){
                        sldGrabacion.setValue(99);
                }
                jInactividad.setText("Estado - Espere: " + jf.getTicksInactividad());
        }
    }

}
